/*
 * Copyright 2008 Carnegie Mellon University
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package edu.cmu.lti.sepia.data.db;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import edu.cmu.lti.sepia.infra.system.model.Permission;
import edu.cmu.lti.sepia.util.ServletUtil;

/**
 * 
 * Manages Permission object in a DB.
 * 
 * @see Permission
 * @author Hideki Shima
 *
 */
public class PermissionDAO {
	
	public static List<Permission> findByUserId( SQL sql, int userId ) throws SQLException {
		String query = Query.generate( Query.FIND_PERMISSION_BY_U, "" );
		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ResultSet rs = null;
		
		List<Permission> permission = new ArrayList<Permission>();
		ps.setInt(1, userId);
		rs = sql.executeSelect(ps);
		while ( rs.next() ) {
			permission.add( rsToObject(rs) );
		}
		rs.close();
		ps.close();
		
		return permission;
	}
	
	public static Permission findByUserAndTaskId( SQL sql, int userId, int taskId ) throws SQLException {
	  String query = Query.generate( Query.FIND_PERMISSION_BY_UT, "" );
	  PreparedStatement ps = sql.getConnection().prepareStatement(query);
	  ResultSet rs = null;
	  
	  Permission permission = null;
	  ps.setInt(1, userId);
	  ps.setInt(2, taskId);
	  rs = sql.executeSelect(ps);
	  if ( rs.next() ) {
	    permission = rsToObject(rs);
	  }
	  rs.close();
	  ps.close();
	  
	  return permission;
	}
	
	public static List<Permission> getPermissions( SQL sql ) throws SQLException {
		String query = Query.generate( Query.GET_PERMISSIONS, "" );
		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ResultSet rs = null;
		
		List<Permission> permission = new ArrayList<Permission>();
		rs = sql.executeSelect(ps);
		while ( rs.next() ) {
			permission.add( rsToObject(rs) );
		}
		rs.close();
		ps.close();
		
		return permission;
	}
	
  public static void updatePermissions( SQL sql, List<Permission> permissions ) throws SQLException {
    String query = Query.generate( Query.UPDATE_PERMISSION, "" );
    
    PreparedStatement ps = sql.getConnection().prepareStatement(query);
    for ( Permission p : permissions ) {
      ps.setInt(1, p.getUserId());
      ps.setInt(2, p.getTaskId());
      ps.setInt(3, p.getPrivilege());
      ps.setInt(4, p.getPrivilege());
      sql.execute(ps);
    }
    ps.close();
  }
  
	private static Permission rsToObject( ResultSet rs ) throws SQLException {
		Permission permission 
		  = new Permission( rs.getInt(1), rs.getInt(2), rs.getInt(3) );
		return permission;
	}
	
  public static JSONObject convertPermissions( List<Permission> permissions ) throws JSONException {
    JSONObject json = new JSONObject();
    JSONArray jsonArray = new JSONArray();
    for ( Permission p : permissions ) {
      JSONObject j = new JSONObject();
      j.put("userId", p.getUserId());
      j.put("taskId", p.getTaskId());
      j.put("privilege", p.getPrivilege());
      jsonArray.put(j);
    }
    json.put("permissions", jsonArray);
    return json;
  }
  
  public static Permission parseRequest( HttpServletRequest request ) {
    ServletUtil s = new ServletUtil( request );
    return new Permission( 
        s.readInt("userId", 0),
        s.readInt("taskId", 0),
        s.readInt("privilege", 0)
    );
  }
  
  public static List<Permission> parseRequestIntoPermissions( HttpServletRequest request ) {
    ServletUtil s = new ServletUtil( request );
    // permissions = 1.2.20,2.4.40,...
    String diff = s.readString("permissions", "");
    List<Permission> permissions = new ArrayList<Permission>();
    // remove duplicated entries first (by overriding with newer ones) 
    Map<String,Integer> map = new LinkedHashMap<String,Integer>();
    String[] triples = diff.split(",");
    for ( String triple : triples ) {
      String[] items = triple.split("\\.");
      map.put(items[0]+"."+items[1], Integer.parseInt(items[2]));
    }
    for ( Entry<String,Integer> entry : map.entrySet() ) {
      String[] items = entry.getKey().split("\\.");
      int userId = Integer.parseInt(items[0]); 
      int taskId = Integer.parseInt(items[1]);
      int privilege = entry.getValue();
      Permission p = new Permission(userId, taskId, privilege);
      permissions.add(p);
    }
    return permissions;
  }
    
}
